﻿#ifndef __REDIS_DB_CONNECTION_POOL_HEAD__
#define __REDIS_DB_CONNECTION_POOL_HEAD__

#include <list>
#include <time.h>
#include <string>
class CRedisDbConnection;
class CRedisDbConnectionPool
{
public:
	CRedisDbConnectionPool(void);
	~CRedisDbConnectionPool(void);


	bool create(size_t szCount
		, const std::string & host
		, const std::string & port_or_socket
		, const std::string & user
		, const std::string & password
		, const std::string & database);


	/// \brief Returns true if pool is empty
	bool empty() const { return pool_.empty(); }


	virtual CRedisDbConnection* exchange(const CRedisDbConnection* pc);

	/// \brief Grab a free connection from the pool.
	virtual CRedisDbConnection* grab();

	/// \brief Return a connection to the pool
	virtual void release(const CRedisDbConnection* pc);

	/// \brief Removes the given connection from the pool
	void remove(const CRedisDbConnection* pc);

	/// \brief Grab a free connection from the pool, testing that it's
	/// connected before returning it.
	virtual CRedisDbConnection* safe_grab();

	/// \brief Remove all unused connections from the pool
	void shrink() { clear(false); }

	/// \brief Drains the pool, freeing all allocated memory.
	void clear(bool all = true);

	/// \brief Returns the current size of the internal connection pool.
	size_t size() const { return pool_.size(); }

	void KeepAlive( int iS );

private:
	//// Internal types
	struct ConnectionInfo
	{
		CRedisDbConnection* conn;
		time_t last_used;
		bool in_use;

		ConnectionInfo(CRedisDbConnection* c)
			: conn(c)
			, last_used(time(0))
			, in_use(false)
		{
		}

		// Strict weak ordering for ConnectionInfo objects.
		// 
		// This ordering defines all in-use connections to be "less
		// than" those not in use.  Within each group, connections
		// less recently touched are less than those more recent.
		bool operator<(const ConnectionInfo& rhs) const
		{
			const ConnectionInfo& lhs = *this;
			return lhs.in_use == rhs.in_use ?
				lhs.last_used < rhs.last_used :
			lhs.in_use;
		}
	};
	typedef std::list<ConnectionInfo> PoolT;
	typedef PoolT::iterator PoolIt;

	//// Internal support functions
	CRedisDbConnection* _find_mru();
	void _remove(const PoolIt& it);

	//// Internal data
	PoolT pool_;
	
	//:todo 连接池加锁

	std::string	    m_host;
	std::string 	m_port_or_socket;
	std::string	    m_user;
	std::string 	m_password;
	std::string	    m_database;

};



#endif
